#ifndef game_font_h
#define game_font_h

#include <string>
#include <vector>
#include "core.h"
#include "screen.h"

namespace font {

    void Init(void);
    class FontImpl;
    
    // The font class. Load using 
    class Font {
    public:
        Font(FontImpl*impl) : impl_(impl) {}
        ~Font();
        // Load the font from the resource directory.
        static Font* Load(const char* name, int size);
        // The height of the font.
        double Height();
    private:
        FontImpl *impl_;
        friend class Draw;
    };
    
    // A class that can render a font.
    // Example use:
    // font::Draw(my_font, 100, 100).add_color(RGB(255, 0, 0)).centered().draw("Hello World");
    // This will write "Hello World" (100, 100) in red with the previously loaded font, centered horizontally.

    class Draw {
    public:
        Draw(Font* font, double x, double y) : font_(font), x_(x), y_(y), colors_(), shadow_(false), center_(false), jiggle_(), outline_(), fixed_advance_(0) {}
        ~Draw() {}
        // Draw the font in this color. If multiple colors are added, the colors alternate with non-space characters.
        Draw &add_color(u32 color) { colors_.push_back(color); return *this; }
        // Also draw a not wonderful drop-shadow.
        Draw &with_shadow() { shadow_ = true; return *this; }
        // Center the output horizontally.
        Draw &centered() { center_ = true; return *this; }
        // Jiggle the letters based on the current time.
        // size = the maximum displacement of the letters, frequency = speed of jiggle.
        Draw &with_jiggle(double size, double frequency) { jiggle_.size = size; jiggle_.frequency = frequency; return *this; }
        // Draw a not wonderful outline around the letters in the given color (EXPENSIVE).
        Draw &with_outline(u32 col) { outline_.enabled = true; outline_.color = col; return *this; }
        // Rather than space the characters out based on the widths of the characters
        // in the font, advance each character by this amount.
        Draw &fixed_advance(double x) { fixed_advance_ = x; return *this; }
        // Render this text.
        void draw(const std::string& text);
    private:
        void push_state();
        void pop_state();
        Font* font_;
        double x_, y_;
        std::vector<u32> colors_;
        bool shadow_;
        bool center_;
        struct {
            double size;
            double frequency;
        } jiggle_;
        struct {
            bool enabled;
            u32 color;
        } outline_;
        double fixed_advance_;
    };
    
}  // namespace font


#endif
